// ProjectName: go-learn-demo
// PackageName: _1_multi_routine
// Description: 开启多个协程
// Author: hy.bai
// Date: 2025-07-30 16:46

package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

// 定义一个全局变量 - 协程计数器,用于记录协程的数量
var wg sync.WaitGroup

// 定义一个互斥锁。等价于:JAVA中的ReentrantLock(可重入锁)
var lock sync.Mutex

func sayHello(i int) {
	lock.Lock()
	// 注:为了避免sayHello方法抛出Panic异常造成Done方法不执行，所以把Done方法的执行放到defer语句块中(无论是否发生异常都会执行)
	defer wg.Done() // 协程执行完毕之后，计数器-1
	fmt.Printf("第%d次---hello go~~~~,协程id是:%d\n", i, runtime.NumGoroutine())
	time.Sleep(100 * time.Microsecond) // 休眠100毫秒
	lock.Unlock()
}

func main() {
	fmt.Printf("--->main线程开始执行,协程id是:%d\n", runtime.NumGoroutine())
	// 开启10个协程。
	for i := 0; i < 10; i++ {
		wg.Add(1) // 协程计数器 +1
		go sayHello(i + 1)
	}
	wg.Wait() // main线程阻塞,等待计数器归零。
	fmt.Printf("--->main线程执行完毕,协程id是%d\n", runtime.NumGoroutine())
}
